<?php
class MajixFactory {
	private $class;
	private $lclass;
	private $result = null;
	private $orderBy = null;
	private $limit_page = null;
	private $limit_rpp = null;

	public function __construct($ini_file_or_array = null) {
		$this->class = substr(get_class($this), 0, -7);
		$this->lclass = strtolower($this->class);

   	if ($this->getConfiguration() === null) {
   		$this->setConfiguration($ini_file_or_array);
		}
	}

	public function getNext() {
		if ($this->result != null) {
			$row = mysqli_fetch_assoc($this->result);
			if ($row != null) {
				$res = new $this->class(Majix::ID_FOR_INJECTION);
				$res->inject($row);
				return $res;
			} else {
				return null;
			}
		} else {
			$this->select();
			if ($this->result != null) {
				return $this->getNext();
			} else {
				return null;
			}
		}
	}

	public function restart() {
		unset($this->result);
		$this->result = null;
	}

	public function orderBy($orderBy) {
		$this->orderBy = $orderBy;
	}

	public function limit($page, $rpp) {
		$this->limit_page = $page;
		$this->limit_rpp = $rpp;
	}

	public function count() {
		if ($this->result !== null) {
			return mysqli_num_rows($this->result);
		} else {
			$this->select();
			return ($this->result !== null ? $this->count() : 0);
		}
	}

	private function select() {
		$c = $this->getConfiguration();

		$this->connect();

		$orderBy = ($this->orderBy != null ? "ORDER BY {$this->orderBy} ": "");
		if ($this->limit_page != null && $this->limit_rpp != null) {
			$start = ($this->limit_page - 1) * $this->limit_rpp;
			$limit = ($this->limit_page != null ? "LIMIT $start, {$this->limit_rpp} ": "");
		} else {
			$limit = "";
		}

		$sql = "SELECT * FROM `{$c[Majix::C_MAJIX][Majix::C_PREPEND]}{$this->lclass}` $orderBy $limit;";

		$this->result = mysqli_query(Majix::$con[$this->class], $sql);
	}

	private function connect() {
		$c = $this->getConfiguration();
		
		$con_id = $c[Majix::C_MYSQL][Majix::C_HOST] . "//" . $c[Majix::C_MYSQL][Majix::C_DBNAME] . "//" . $c[Majix::C_MYSQL][Majix::C_PREPEND];

		if (isset(Majix::$con[$con_id])) {
			return;
		}

		if ((Majix::$con[$con_id] = mysqli_connect($c[Majix::C_MYSQL][Majix::C_HOST], $c[Majix::C_MYSQL][Majix::C_USERNAME], $c[Majix::C_MYSQL][Majix::C_PASSWD], $c[Majix::C_MYSQL][Majix::C_DBNAME])) === FALSE) {
			throw new MajixException("Could not connect to MySQL database ({$this->class}): " . mysqli_connect_error());
		}
	}

   private function getConfiguration() {
   	return isset(Majix::$config[$this->class]) ? Majix::$config[$this->class] : null;
	}

	private function setConfiguration($ini_file_or_array) {
		if ($ini_file_or_array === null) {
			$ini_file_or_array = _MAJIX_INI_FILE;
		}

		if (is_array($ini_file_or_array)) {
			Majix::$config[$this->class] = $ini_file_or_array;
		} else if (is_string($ini_file_or_array)) {
			Majix::$config[$this->class] = parse_ini_file($ini_file_or_array, true);
		} else {
			throw new MajixException("Could not configure Majix Factory class, " . $this->class . ".");
		}
		foreach(Majix::$config_layout as $section => $section_arr) {
			if (!isset(Majix::$config[$this->class][$section])) {
				throw new MajixException("Configuration section, $section, is missing.");
			}
			foreach ($section_arr as $setting) {
				if (!isset(Majix::$config[$this->class][$section][$setting])) {
					throw new MajixException("Configuration setting, [$section]:$setting, is missing.");
				}
			}
		}
	}
}
